home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
comm
/
qhead.zip
/
QHEAD.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-07-08
|
18KB
|
589 lines
PROGRAM QHead; {v1.25 - Free DOS utility: Get message headers from QWK files.}
{$M 5120,0,0} { 5k stack, no heap needed }
{$N-,E- no math support needed}
{$X- function calls may not be discarded}
{$I- disable I/O checking (trap errors by checking IOResult)}
{===========================================================================}
(** Global declarations ... **)
{===========================================================================}
USES
DOS, ARCID;
CONST
cursorState : BYTE = 1; {0..3}
cursorData : ARRAY [0..3] OF CHAR = (#179, #47, #196, #92);
VAR
unQWK, unARC, unARJ, unHAP, unLZH,
unPAK, unRAR, unUC2, unZIP, unZOO : PATHSTR;
qheader, qline : string[128];
confnumb : WORD;
ExtractAll : Boolean;
QWKname : string[13];
{===========================================================================}
(** Custom help & exit procedure ... **)
{===========================================================================}
VAR SavedExitProc: POINTER;
PROCEDURE cursorOn; FORWARD;
FUNCTION WordToHex (i: WORD): STRING; FORWARD;
PROCEDURE CustomExit; FAR;
{---- Always exit through here ----}
CONST
NL = #13#10;
VAR
message: STRING [79];
BEGIN
ExitProc := SavedExitProc;
cursorOn;
IF (ExitCode > 0) THEN BEGIN
Writeln('QHead v1.25 - Free DOS utility: Extract message headers from QWK packets.');
WriteLn ('July 8, 1996. Copyright (c) 1996 by David Daniel Anderson - Reign Ware.'+NL);
Writeln('Usage: QHead <QWKpacket(s)> [conference]'+NL);
Writeln('Where: "[conference]" is any valid DOS filename, with an embedded conference');
Writeln(' number. If no number is found embedded within the filename, then');
Writeln(' *all* the conference headers in the QWK packet will be extracted.'+NL);
Writeln('Examples: QHead c:\qwks\*.qwk cnf100.hdr');
Writeln(' QHead c:\qwk\channel1.qwk ch-all.hdr');
Writeln(' QHead *.qwk [writes all headers to "QHEAD.OUT"]'+NL);
Writeln('Note: DOS wildcards may be used when specifying the QWKpackets.');
END;
IF ErrorAddr <> NIL THEN {If an unanticipated run-time error occured...}
BEGIN
WriteLn ('An unanticipated error occurred, please contact DDA with the following data:');
WriteLn ('Address = ', WordToHex (Seg (ErrorAddr^)), ':', WordToHex (Ofs (ErrorAddr^)));
WriteLn ('Code = ', ExitCode);
ErrorAddr := NIL; {IMPORTANT!!!}
END
ELSE
IF (ExitCode IN [1..254]) THEN BEGIN
CASE ExitCode OF
1 : message := 'Invalid parameter on command line or parameter missing.';
2 : message := 'No files found. First parameter must be a valid file specification.';
3 : message := 'The second parameter must contain a conference number.';
5 : message := 'Not enough memory to extract MESSAGES.DAT - aborting!';
6 : message := 'You cannot just specify a path, add "*.*" or "\*.*" for all files.';
7 : message := 'File handling error. File may have been corrupted or deleted!';
ELSE message := 'Unknown error.';
END;
WriteLn (#7, 'Error encountered (#', ExitCode, '):'); WriteLn (message);
END;
END;
{===========================================================================}
(** Supporting subroutines ... **)
{===========================================================================}
FUNCTION WordToHex (i: WORD): STRING; {Convert a WORD variable to STRING}
CONST
HexLetters : ARRAY [0..15] OF CHAR = '0123456789ABCDEF';
BEGIN
WordToHex := Concat (HexLetters [Hi (i) SHR 4], HexLetters [Hi (i) AND 15],
HexLetters [Lo (i) SHR 4], HexLetters [Lo (i) AND 15]);
END;
PROCEDURE CheckIO;
BEGIN
IF IOResult <> 0 THEN Halt (7);
END;
PROCEDURE cursorOn; ASSEMBLER; ASM
mov AH, 3; mov BH, 0; Int $10; AND CH, NOT $20; mov AH, 1; Int $10;
END;
PROCEDURE cursorOff; ASSEMBLER; ASM
mov AH, 3; mov BH, 0; Int $10; OR CH, $20; mov AH, 1; Int $10;
END;
PROCEDURE updateCursor;
BEGIN
cursorState := Succ (cursorState) AND 3;
Write (cursorData [cursorState], ^H);
END;
FUNCTION WhereX: BYTE; ASSEMBLER;
(* Routine from SWAG *)
ASM
MOV AH, 3 {Ask For current cursor position}
MOV BH, 0 { On page 0 }
Int 10h { Return inFormation in DX }
Inc DL { Bios Assumes Zero-based. Crt.WhereX Uses 1 based }
MOV AL, DL { Return X position in AL For use in Byte Result }
END;
FUNCTION WhereY: BYTE; ASSEMBLER;
(* Routine from SWAG *)
ASM
MOV AH, 3 {Ask For current cursor position}
MOV BH, 0 { On page 0 }
Int 10h { Return inFormation in DX }
Inc DH { Bios Assumes Zero-based. Crt.WhereY Uses 1 based }
MOV AL, DH { Return Y position in AL For use in Byte Result }
END;
PROCEDURE GotoXY (X, Y: BYTE); ASSEMBLER;
(* Routine from SWAG *)
ASM
MOV DH, Y { DH = Row (Y) }
MOV DL, X { DL = Column (X) }
Dec DH { Adjust For Zero-based Bios routines }
Dec DL { Turbo Crt.GotoXY is 1-based }
MOV BH, 0 { Display page 0 }
MOV AH, 2 { Call For SET CURSOR POSITION }
Int 10h
END;
PROCEDURE WriteCharAtCursor (X: CHAR);
(* Routine from SWAG *)
VAR
reg: REGISTERS;
BEGIN
reg. AH := $0A;
reg. AL := Ord (X);
reg. BH := $00; {* Display Page Number. * for Graphics Modes! *}
reg. CX := 1; {* Word for number of characters to write *}
Intr ($10, reg);
END;
PROCEDURE ClrEol;
(* Routine by DDA *)
VAR
NumCol: WORD ABSOLUTE $0040: $004A; { Number of CRT columns (1-based) }
X, Y, DistanceToRight: BYTE;
BEGIN
X := WhereX;
Y := WhereY;
DistanceToRight := NumCol - X;
Write ('': DistanceToRight);
WriteCharAtCursor (#32);
GotoXY (X, Y);
END;
FUNCTION LeadingZero (w : WORD) : STRING;
VAR
s : STRING;
BEGIN
Str (w: 0, s);
IF Length (s) = 1 THEN
s := '0' + s;
LeadingZero := s;
END;
PROCEDURE UpFast (VAR Str: STRING); {** from SWAG **}
INLINE ($8C/$DA/$5E/$1F/$FC/$AC/$30/$E4/$89/$C1/$E3/$12/$BB/Ord('a')/Ord('z')/
$AC/$38/$D8/$72/$08/$38/$F8/$77/$04/$80/$6C/$FF/$20/$E2/$F1/$8E/$DA);
FUNCTION Upper (lstr : STRING): STRING;
BEGIN
upfast (lstr);
Upper := lstr;
END;
FUNCTION RPad (bstr: STRING; len: BYTE): STRING;
BEGIN
WHILE (Length (bstr) < len) DO
bstr := bstr + #32;
RPad := bstr;
END;
FUNCTION RTrim (InStr: STRING): STRING;
BEGIN
WHILE (Length (InStr) > 0) AND (InStr [Length (InStr)] IN [#0, #9, #32]) DO
Dec (InStr [0]);
RTrim := InStr;
END;
FUNCTION LTrim (InStr: STRING): STRING;
BEGIN
WHILE (Length (InStr) > 0) AND (InStr [1] IN [#0, #9, #32]) DO
Delete (InStr, 1, 1);
LTrim := InStr;
END;
FUNCTION Squeeze (ss: STRING): STRING;
VAR
controlCHAR: CHAR;
BEGIN
FOR controlCHAR := #0 TO #31 DO
WHILE (Ord (ss [0]) > 0) AND (Pos (controlCHAR, ss) > 0) DO
ss [Pos (controlCHAR, ss)] := #32;
Squeeze := RTrim (LTrim (ss));
END;
FUNCTION IsFile (CONST FileName: PATHSTR): BOOLEAN;
VAR
Attr : WORD;
cFile : FILE;
BEGIN
Assign (cFile, FileName);
GetFAttr (cFile, Attr);
IF (DosError = 0) AND ((Attr AND Directory) <> Directory)
THEN IsFile := TRUE
ELSE IsFile := FALSE;
END;
PROCEDURE EraseFile (CONST FileName : STRING);
VAR
cFile : FILE;
BEGIN
IF IsFile (FileName) THEN BEGIN
Assign (cFile, FileName);
SetFAttr (cFile, 0);
Erase (cFile); CheckIO;
END;
END;
FUNCTION IsDir (CONST FileName: PATHSTR): BOOLEAN;
VAR
Attr : WORD;
cFile : FILE;
BEGIN
Assign (cFile, FileName);
GetFAttr (cFile, Attr);
IF (DosError = 0) AND ((Attr AND Directory) = Directory)
THEN IsDir := TRUE
ELSE IsDir := FALSE;
END;
FUNCTION GetFilePath (CONST PSTR: STRING; VAR sDir: DIRSTR): PATHSTR;
VAR
jPath : PATHSTR; { file path, }
jDir : DIRSTR; { directory, }
jName : NAMESTR; { name, }
jExt : EXTSTR; { extension. }
BEGIN
jPath := PSTR;
IF jPath = '' THEN jPath := '*.*';
IF (NOT (jPath [L